import java.io.IOException;

import jxl.write.WriteException;

public class TestSetup {

	private static int firstElement;
	private static int lastElement;
	private static int nrOfSteps;
	private static int nrOfReps;

	public static void main(String[] args) {

		Tester test;
		Tester2 test2;
		Sorter[] algorithms;
		String[] labels;
		double[][] runTimes;
		int testmode;

		if (args.length < 1) {
			System.out.println("\nYou have to provide a mode argument: 1 or 2");
			System.out.println("Mode 1: Allows you to test multiple "
					+ "algorithms with some test parameters.");
			System.out
					.println("Mode 2: Here a Quicksort algorithm is tested with "
							+ "the same parameters as in mode 1 "
							+ "with the addition of array presortedness parameters.");
			System.exit(-1);
		}
		testmode = Integer.parseInt(args[0]);
		if (testmode == 1) {
			// Order of arguments should be: interval start integer, interval
			// end
			// integer, number of steps to divide the interval into, number of
			// repetitions of each step interval, sorting method keyword(s).
			if (args.length < 6) {
				System.out
						.println("\n-You have to provide the following arguments-");
				System.out.println("1: Tester mode, which should be a 1");
				System.out.println("2: First integer in interval,");
				System.out.println("3: Last integer in interval,");
				System.out
						.println("4: Number of steps the interval should be clocked,");
				System.out.println("5: How many times each step"
						+ " interval should be repeated,");
				System.out.println(">6: Sorting algorithm(s) to test using"
						+ " atleast one of the following keyword(s):");
				System.out.println("heap:        Heapsort algorithm");
				System.out.println("m3quick:     M3Quicksort algorithm, pivot"
						+ " is median of three(first, middle, last)");
				System.out.println("quick:       Regular Quicksort algorithm,"
						+ " pivot is last index");
				System.out.println("simplemerge: Regular Mergesort algorithm,"
						+ " recursive array allocations");
				System.out.println("merge:       Mergesort algorithm,"
						+ " only uses two array allocations");
				System.out
						.println("fastmerge:       Faster Mergesort algorithm,"
								+ " only uses two allocations, but has fewer variable assignments than the previous Mergesort");
				System.exit(-1);
			}
			setUniversalParameters(args);
			algorithms = new Sorter[args.length - 5];
			labels = new String[args.length - 5];
			for (int i = 5; i < args.length; i++) {
				labels[i - 5] = args[i];
				if (args[i].equals("heap")) {
					algorithms[i - 5] = new Heapsort();
				} else if (args[i].equals("m3quick")) {
					algorithms[i - 5] = new M3Quicksorter();
				} else if (args[i].equals("quick")) {
					algorithms[i - 5] = new Quicksorter();
				} else if (args[i].equals("simplemerge")) {
					algorithms[i - 5] = new SimpleMergesorter();
				} else if (args[i].equals("merge")) {
					algorithms[i - 5] = new MergeSorter();
				} else if (args[i].equals("fastmerge")) {
					algorithms[i - 5] = new FasterMergeSorter();
				}
			}
			test = new Tester(firstElement, lastElement, nrOfReps, nrOfSteps,
					algorithms);
			runTimes = test.startTesting();
			makeSpreadSheet(runTimes, labels, test.getStepArray());
			System.out.println("All tests have finished.");
		} else {
			if (args.length < 5) {
				System.out
						.println("\n-You have to provide the following arguments-");
				System.out.println("1: Tester mode, which should be a 2");
				System.out.println("2: First integer in interval,");
				System.out.println("3: Last integer in interval,");
				System.out
						.println("4: Number of steps the interval should be clocked,");
				System.out
						.println("5: How many times each step interval should be repeated,");
				System.out
						.println("6: The lower bound(l) for presortedness 0 <= l < u <= 1,");
				System.out
						.println("7: The upper bound(u) for presortedness 0 <= l < u <= 1,");
				System.out
						.println("8: How many steps the interval from u to l should be divided.");
				System.exit(-1);
			}
			setUniversalParameters(args);
			double low = Double.parseDouble(args[5]);
			double hi = Double.parseDouble(args[6]);
			int num = Integer.parseInt(args[7]);
			test2 = new Tester2(firstElement, lastElement, nrOfReps, nrOfSteps,
					new Quicksorter(), low, hi, num);
			double[][] testResults = test2.test();
			double[] presortedness = test2.getPreSortInterval();
			String[] preSortLabels = new String[presortedness.length];
			// Changing the look of the percentage scale to 0-100 numbers
			for (int i = 0; i < preSortLabels.length; i++) {
				String str = String.valueOf((double) Math
						.round(presortedness[i] * 10000) / 10000);
				preSortLabels[i] = str + " quick";

			}
			makeSpreadSheet(testResults, preSortLabels, test2.getStepArray());

			System.out.println("All tests have finished.");

		}
	}

	private static void setUniversalParameters(String[] args) {
		firstElement = Integer.parseInt(args[1]);
		lastElement = Integer.parseInt(args[2]);
		nrOfSteps = Integer.parseInt(args[3]);
		nrOfReps = Integer.parseInt(args[4]);
	}

	private static void makeSpreadSheet(double[][] testResult,
			String[] sorterLabels, int[] intervalLimits) {
		SpreadsheetMaker xcelSheet = new SpreadsheetMaker();
		try {
			xcelSheet.makeSpreadsheet(testResult, sorterLabels, intervalLimits);
		} catch (WriteException | IOException e) {
			System.out.println("Could not create spreadsheet!");
		}
	}
}
